import numpy as np
import pandas as pd
from django.http import JsonResponse
from django.shortcuts import render

from apps.mapper.sql_connect import read_user_info, read_output_data_from_db, read_machine_data_from_db, \
    read_rain_data_from_db, read_seed_area_data_from_db, read_temperature_data_from_db


# Create your views here.

# 登录注册界面-->通用角色界面
def home(request):
    return render(request, 'login_register.html')


# 后台界面-->管理员权限
def backend(request):
    status = request.GET.get('status')
    if status == "user":
        response = {
            "code": 0,
            "message": f"进入后台失败，只有管理员才可进入后台进行操作，您当前的身份为{status}",
            "data": None
        }
        return JsonResponse(response)
    else:
        user_data = read_user_info()
        data = [tuple(row) for _, row in user_data.iterrows()]
        response = {
            "code": 0,
            "message": f"欢迎您，{status}",
            "data": data
        }
        return render(request, 'user_manage.html', response)


# 数据管理界面-->管理员权限
def data_manage(request):
    return render(request, 'data_manage.html')


# 数据可视化界面-->通用权限
def visualize(request):
    # 获取登录的用户身份
    status = request.GET.get('status')

    # 获取农作物产量数据
    output_data: pd.DataFrame = read_output_data_from_db()
    # 将place含有"计"的记录去掉
    output_data = output_data[~output_data['place'].str.contains("计")]
    output_data['year'] = pd.to_datetime(output_data['year'])
    print(output_data['year'])

    # 计算各place对应的food_name的产量总和,返回一个可以print出来的dataframe
    output_data_sum = output_data.groupby(['place', 'food_name'])['output'].sum().reset_index()
    # 统计产量综合最高的9个place,返回一个列表，列表里面装着place和对应的产量总和以及产量占比
    top_9_place_list = output_data_sum.groupby('place')['output'].sum().nlargest(9).reset_index()
    # 得到每个place对应的产量占比
    top_9_ratio_list = (top_9_place_list['output'] / top_9_place_list['output'].sum() * 100).round(2).tolist()
    # 将top_9_ratio_list中的占比从小到大排序
    top_9_ratio_list.sort()
    # 将top_9_place_list中的place和对应的产量总和以及产量占比合并成一个列表
    top_9_place_list = top_9_place_list.values.tolist()

    # 计算总产量的值，返回一个数字
    total_production = output_data['output'].sum()

    # 计算food_name对应的产量总和，选择最高的3个，返回一个列表，列表里面装着food_name和对应的产量总和
    top_3_food_list = output_data.groupby('food_name')['output'].sum().nlargest(3).reset_index()
    # 得到每个food_name对应的产量占比
    top_3_ratio_list = (top_3_food_list['output'] / top_3_food_list['output'].sum() * 100).round(2).tolist()
    # 将top_3_ratio_list中的占比从小到大排序
    top_3_ratio_list.sort(reverse=True)

    # 得到对应的food_name
    top_3_food_name_list = top_3_food_list['food_name'].tolist()

    # 计算产量的变化趋势，返回一个列表，列表里面装着日期和对应的产量值
    output_data['year'] = pd.to_datetime(output_data['year'])
    output_data = output_data.sort_values(by='year')
    output_data['year'] = output_data['year'].dt.strftime('%Y')
    output_data_trend = output_data.groupby('year')['output'].sum().reset_index()
    output_data_trend = output_data_trend.values.tolist()
    # 计算产量占比变化趋势，返回一个列表，列表里面装着日期和对应的产量占比
    output_data_ratio_trend = (output_data.groupby('year')['output'].sum() / output_data['output'].sum() * 100).round(
        2).reset_index()
    output_data_ratio_trend = output_data_ratio_trend.values.tolist()
    print(output_data_trend)

    # 读取机械拥有量数据
    machine_data = read_machine_data_from_db()
    # 将value列转为float类型
    machine_data['value'] = machine_data['value'].astype(float)
    # 去除machine_name列中的"\n"和空格
    machine_data['machine_name'] = machine_data['machine_name'].str.replace("\n", " ").str.strip()
    # 去除place为"计"的记录
    machine_data = machine_data[~machine_data['place'].str.contains("计")]
    # 按year分组，计算machine_name对应的value的平均值，返回一个列表，列表的元素是元组，包含year、machine_name、平均值
    machine_data_avg = machine_data.groupby(['year', 'machine_name'])['value'].mean().reset_index()
    # 去除machine_name值中含有千瓦的记录
    machine_data_avg = machine_data_avg[~machine_data_avg['machine_name'].str.contains("千瓦")]
    # 得到每个machine_name对应的平均值
    machine_data_avg_list = machine_data_avg.values.tolist()

    # 获取列表中含有农用大中型拖拉机数量(台)的元素
    big_tractor = [x for x in machine_data_avg_list if "农用大中型拖拉机" in x[1]]
    small_tractor = [x for x in machine_data_avg_list if "小型拖拉机数量" in x[1]]
    big_farmer_tool = [x for x in machine_data_avg_list if "节水灌溉机械数量" in x[1]]

    # 读取降雨量数据
    rain_data = read_rain_data_from_db()
    # 将value列转为float类型
    rain_data['value'] = rain_data['value'].astype(float)
    # 保存两位小数
    rain_data['value'] = rain_data['value'].round(2)
    # 按year分组，计算value的平均值，返回一个列表，列表的元素是元组，包含year、平均值保存为两位小数
    rain_data_avg = rain_data.groupby('year')['value'].mean().reset_index()
    rain_data_avg['value'] = rain_data_avg['value'].round(2)
    # 得到每个year对应的平均值
    rain_data_avg_list = rain_data_avg.values.tolist()

    # 读取种植面积数据
    seed_area_data = read_seed_area_data_from_db()
    # 将value列转为float类型
    seed_area_data['value'] = seed_area_data['value'].astype(float)
    # 保存两位小数
    seed_area_data['value'] = seed_area_data['value'].round(2)
    # 按year分组，计算value的平均值，返回一个列表，列表的元素是元组，包含year、平均值保存为两位小数
    seed_area_data_avg = seed_area_data.groupby('year')['value'].mean().reset_index()
    seed_area_data_avg['value'] = seed_area_data_avg['value'].round(0)
    # 得到每个year对应的平均值
    seed_area_data_avg_list = seed_area_data_avg.values.tolist()

    # 读取温度数据
    temperature_data = read_temperature_data_from_db()
    # 将value列转为float类型
    temperature_data['value'] = temperature_data['value'].astype(float)

    # 保存两位小数
    temperature_data['value'] = temperature_data['value'].round(2)
    # 数据中的month字段包含了月份，基于年份且基于月份进行分组，计算value的平均值，返回一个列表，列表的元素是元组，包含year、month、平均值保存为两位小数
    temperature_data_avg = temperature_data.groupby(['year', 'month'])['value'].mean().reset_index()
    temperature_data_avg['value'] = temperature_data_avg['value'].round(2)
    # 得到每个year、month对应的平均值
    temperature_data_avg_list = temperature_data_avg.values.tolist()
    # 拆分为2018、2019、2020年的数据
    temperature_data_2018 = [x for x in temperature_data_avg_list if x[0] == 2018]
    temperature_data_2019 = [x for x in temperature_data_avg_list if x[0] == 2019]
    temperature_data_2020 = [x for x in temperature_data_avg_list if x[0] == 2020]

    # 构造返回数据
    response = {
        'code': 1,
        'message': "success",
        "data": status,
        'top_9_place_list': top_9_place_list,
        'top_9_ratio_list': top_9_ratio_list,
        'total_production': total_production,
        'top_3_food_name_list': top_3_food_name_list,
        'top_3_ratio_list': top_3_ratio_list,
        'output_data_trend': output_data_trend,
        'output_data_ratio_trend': output_data_ratio_trend,
        'big_tractor': big_tractor,
        'small_tractor': small_tractor,
        'big_farmer_tool': big_farmer_tool,
        'rain_data_avg_list': rain_data_avg_list,
        'seed_area_data_avg_list': seed_area_data_avg_list,
        'temperature_data_2018': temperature_data_2018,
        'temperature_data_2019': temperature_data_2019,
        'temperature_data_2020': temperature_data_2020
    }
    return render(request, 'visualize.html', response)


# 影响因素查询界面
def search_web(request):
    # 读取产量数据
    output_data = read_output_data_from_db()
    # 读取机械拥有量数据
    machine_data = read_machine_data_from_db()
    # 读取降雨量数据
    rain_data = read_rain_data_from_db()
    # 读取种植面积数据
    seed_area_data = read_seed_area_data_from_db()
    # 读取温度数据
    temperature_data = read_temperature_data_from_db()

    # 计算2018年\2019年\2020年的平均降雨量,保存为两位小数的列表
    rain_data_avg_list = []
    rain_data_avg_list.append(rain_data[rain_data['year'] == 2018]['value'].mean().round(2))
    rain_data_avg_list.append(rain_data[rain_data['year'] == 2019]['value'].mean().round(2))
    rain_data_avg_list.append(rain_data[rain_data['year'] == 2020]['value'].mean().round(2))
    # 计算2018年\2019年\2020年的平均种植面积,保存为整数的列表
    seed_area_data_avg_list = []
    seed_area_data_avg_list.append(seed_area_data[seed_area_data['year'] == 2018]['value'].mean().round(0))
    seed_area_data_avg_list.append(seed_area_data[seed_area_data['year'] == 2019]['value'].mean().round(0))
    seed_area_data_avg_list.append(seed_area_data[seed_area_data['year'] == 2020]['value'].mean().round(0))
    # 计算2018年\2019年\2020年的平均温度,保存为两位小数的列表
    temperature_data_avg_list = []
    temperature_data_avg_list.append(temperature_data[temperature_data['year'] == 2018]['value'].mean().round(2))
    temperature_data_avg_list.append(temperature_data[temperature_data['year'] == 2019]['value'].mean().round(2))
    temperature_data_avg_list.append(temperature_data[temperature_data['year'] == 2020]['value'].mean().round(2))

    #
    machine_data_avg_list = []
    # 计算2018年\2019年\2020年的平均农用大中型拖拉机数量,保存为整数的列表
    # 转换数据类型
    machine_data['value'] = machine_data['value'].astype(float)
    big_tractor_avg_list = []
    small_tractor_avg_list = []
    big_farmer_tool_avg_list = []
    for year in [2018, 2019, 2020]:
        # 读取机械拥有量数据
        machine_data_year = machine_data[machine_data['year'] == year]
        # 计算2018年\2019年\2020年的平均农用大中型拖拉机数量,保存为整数的列表
        big_tractor_avg_list.append(
            machine_data_year[machine_data_year['machine_name'].str.contains("农用大中型拖拉机")]['value'].mean().round(
                0))
        small_tractor_avg_list.append(
            machine_data_year[machine_data_year['machine_name'].str.contains("小型拖拉机数量")]['value'].mean().round(
                0))
        big_farmer_tool_avg_list.append(
            machine_data_year[machine_data_year['machine_name'].str.contains("节水灌溉机械数量")]['value'].mean().round(
                0))
    # 计算2018年\2019年\2020年的平均产量,保存为整数的列表
    output_data_avg_list = []
    output_data_avg_list.append(output_data[output_data['year'] == 2018]['output'].mean().round(0))
    output_data_avg_list.append(output_data[output_data['year'] == 2019]['output'].mean().round(0))
    output_data_avg_list.append(output_data[output_data['year'] == 2020]['output'].mean().round(0))
    # 将所有数据保存到dataframe中
    data = pd.DataFrame({
        'rain_data_avg_list': rain_data_avg_list,
        'seed_area_data_avg_list': seed_area_data_avg_list,
        'temperature_data_avg_list': temperature_data_avg_list,
        'big_tractor_avg_list': big_tractor_avg_list,
        'small_tractor_avg_list': small_tractor_avg_list,
        'big_farmer_tool_avg_list': big_farmer_tool_avg_list,
        'output_data_avg_list': output_data_avg_list
    })

    # 计算两两因素的Pearson相关系数
    pearson_corr = data.corr()
    # 计算两两因素的Spearman相关系数
    spearman_corr = data.corr('spearman')
    # 将两两相关的影响因素的名称、对应的相关系数保存在一个列表中
    corr_list = []
    for i in range(len(pearson_corr.columns)):
        for j in range(i + 1, len(pearson_corr.columns)):
            # 计算Pearson相关系数,添加的元素为(因素1名称,因素2名称,Pearson相关系数,Spearman相关系数)
            corr_list.append(
                (pearson_corr.columns[i], pearson_corr.columns[j], pearson_corr.iloc[i, j],
                 np.round(spearman_corr.iloc[i, j], 2)))

    # 根据相关系数得出数据分析报告
    # 建立一个字典，用来对应每个英文单词，中文单词，以及对应的中文解释
    word_dict = {
        'rain_data_avg_list': "平均降雨量",
        'seed_area_data_avg_list': "平均种植面积",
        'temperature_data_avg_list': "平均气温",
        'big_tractor_avg_list': "平均农用大中型拖拉机数量",
        'small_tractor_avg_list': "平均小型拖拉机数量",
        'big_farmer_tool_avg_list': "平均节水灌溉机械数量",
        'output_data_avg_list': "平均产量",
    }
    # 生成一个数据报告
    reports = []
    for i in range(len(corr_list)):
        # 比较每两个因素的相关系数大小,相关系数大于0.8表示有强烈的正相关关系,小于-0.8表示有强烈的负相关关系,处于0.1到0.5之间表示有弱的正相关关系,处于-0.5到-0.1之间表示有弱的负相关关系，其他情况表示无明显相关关系
        if corr_list[i][2] > 0.8:
            report = "因素" + word_dict[corr_list[i][0]] + "与因素" + word_dict[
                corr_list[i][1]] + "存在强烈的正相关关系，相关系数为" + str(
                corr_list[i][2]) + "，Spearman相关系数为" + str(corr_list[i][3]) + "。"
            reports.append(report)
        elif corr_list[i][2] < -0.8:
            report = "因素" + word_dict[corr_list[i][0]] + "与因素" + word_dict[
                corr_list[i][1]] + "存在强烈的负相关关系，相关系数为" + str(
                corr_list[i][2]) + "，Spearman相关系数为" + str(corr_list[i][3]) + "。"
            reports.append(report)
        elif corr_list[i][2] > 0.1 and corr_list[i][2] < 0.5:
            report = "因素" + word_dict[corr_list[i][0]] + "与因素" + word_dict[
                corr_list[i][1]] + "存在弱的正相关关系，相关系数为" + str(corr_list[i][2]) + "，Spearman相关系数为" + str(
                corr_list[i][3]) + "。"
            reports.append(report)
        elif corr_list[i][2] < -0.5 and corr_list[i][2] > -0.1:  # 负相关关系
            report = "因素" + word_dict[corr_list[i][0]] + "与因素" + word_dict[
                corr_list[i][1]] + "存在弱的负相关关系，相关系数为" + str(corr_list[i][2]) + "，Spearman相关系数为" + str(
                corr_list[i][3]) + "。"
            reports.append(report)
        else:
            report = "因素" + word_dict[corr_list[i][0]] + "与因素" + word_dict[
                corr_list[i][1]] + "无明显相关关系，相关系数为" + str(corr_list[i][2]) + "，Spearman相关系数为" + str(
                corr_list[i][3]) + "。"
            reports.append(report)
        # 打印报告
    # 构造返回数据
    response = {
        'code': 1,
        'message': "success",
        'corr_list': corr_list,
        'reports': reports
    }
    return render(request, 'search.html', response)
